//! HTTP Plugin for AI Test Platform
//! 
//! This plugin provides HTTP request functionality using Extism PDK.

use extism_pdk::*;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

/// HTTP request structure
#[derive(Debug, Serialize, Deserialize)]
pub struct HttpRequest {
    pub method: String,
    pub url: String,
    pub headers: Option<HashMap<String, String>>,
    pub body: Option<String>,
    pub timeout: Option<u64>,
}

/// HTTP response structure
#[derive(Debug, Serialize, Deserialize)]
pub struct HttpResponse {
    pub status: u16,
    pub headers: HashMap<String, String>,
    pub body: String,
    pub elapsed_ms: u64,
}

/// Plugin configuration
#[derive(Debug, Serialize, Deserialize)]
pub struct PluginConfig {
    pub default_timeout: Option<u64>,
    pub user_agent: Option<String>,
    pub follow_redirects: Option<bool>,
}

/// Execute HTTP request
#[plugin_fn]
pub fn execute_request(input: String) -> FnResult<String> {
    let request: HttpRequest = serde_json::from_str(&input)
        .map_err(|e| WithReturnCode::new(Error::msg(format!("Invalid request format: {}", e)), 1))?;
    
    // For now, return a mock response since we can't make actual HTTP requests in WASM
    // In a real implementation, this would use a HTTP client
    let response = HttpResponse {
        status: 200,
        headers: {
            let mut headers = HashMap::new();
            headers.insert("content-type".to_string(), "application/json".to_string());
            headers
        },
        body: r#"{"message": "Mock response from HTTP plugin", "url": ""#.to_string() + &request.url + r#""}"#,
        elapsed_ms: 100,
    };
    
    let response_json = serde_json::to_string(&response)
        .map_err(|e| WithReturnCode::new(Error::msg(format!("Failed to serialize response: {}", e)), 1))?;
    
    Ok(response_json)
}

/// Validate HTTP request
#[plugin_fn]
pub fn validate_request(input: String) -> FnResult<String> {
    let request: HttpRequest = serde_json::from_str(&input)
        .map_err(|e| WithReturnCode::new(Error::msg(format!("Invalid request format: {}", e)), 1))?;
    
    // Basic validation
    if request.url.is_empty() {
        return Err(WithReturnCode::new(Error::msg("URL cannot be empty"), 1));
    }
    
    if !request.url.starts_with("http://") && !request.url.starts_with("https://") {
        return Err(WithReturnCode::new(Error::msg("URL must start with http:// or https://"), 1));
    }
    
    let valid_methods = ["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"];
    if !valid_methods.contains(&request.method.to_uppercase().as_str()) {
        return Err(WithReturnCode::new(Error::msg("Invalid HTTP method"), 1));
    }
    
    Ok(r#"{"valid": true}"#.to_string())
}

/// Get plugin information
#[plugin_fn]
pub fn get_info() -> FnResult<String> {
    let info = serde_json::json!({
        "name": "HTTP Plugin",
        "version": "0.1.0",
        "description": "HTTP request plugin for AI Test Platform",
        "functions": ["execute_request", "validate_request", "get_info"],
        "capabilities": {
            "methods": ["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"],
            "protocols": ["http", "https"],
            "features": ["headers", "body", "timeout"]
        }
    });
    
    Ok(info.to_string())
}

/// Initialize plugin with configuration
#[plugin_fn]
pub fn initialize(input: String) -> FnResult<String> {
    let _config: PluginConfig = serde_json::from_str(&input)
        .map_err(|e| WithReturnCode::new(Error::msg(format!("Invalid config format: {}", e)), 1))?;
    
    // Store configuration in plugin state if needed
    // For now, just return success
    Ok(r#"{"initialized": true}"#.to_string())
}
